% Ejercicio "Análisis de fichero log de HTTP"
\section*{\fbox{\theejercicio} - An\'alisis de fichero log de HTTP}

La WWW se basa en un protocolo cliente/servidor denominado HTTP. En cada nodo al que se accede existe un programa activo continuamente a la espera de conexiones que implementa al servidor de este protocolo. Este programa genera automáticamente un fichero de traza con la informaci\'on de todos aquellos clientes que se han conectado a \'el. El siguiente es un ejemplo de un trozo de este fichero de traza:

{\scriptsize \begin{verbatim}
alcor.lcc.uma.es - - [10/Feb/1998:11:29:12 +0100] "POST /cgi-bin/cesar/wisar HTTP/1.0" 200 873
alcor.lcc.uma.es - - [10/Feb/1998:11:29:17 +0100] "POST /cgi-bin/cesar/wisar HTTP/1.0" 200 594
195.53.21.4 - - [10/Feb/1998:11:30:26 +0100] "GET /docencia/ETSIInf/asignat_cursos.html HTTP/1.0" 304 0
195.53.21.4 - - [10/Feb/1998:11:30:31 +0100] "GET /docencia/gif/fac-back.gif HTTP/1.0" 404 -
195.53.21.4 - - [10/Feb/1998:11:30:39 +0100] "GET /docencia/gif/fac-back.gif HTTP/1.0" 404 -
baltasar.uca.es - - [10/Feb/1998:11:31:28 +0100] "GET / HTTP/1.0" 200 2092
baltasar.uca.es - - [10/Feb/1998:11:31:29 +0100] "GET /gif/english.flag.gif HTTP/1.0" 200 129
baltasar.uca.es - - [10/Feb/1998:11:31:29 +0100] "GET /gif/fondo_inf.gif HTTP/1.0" 200 4411
baltasar.uca.es - - [10/Feb/1998:11:31:30 +0100] "GET /cgi-bin/Count.cgi?dd=B|df=index.dat HTTP/1.0" 200 2236
himalia.lcc.uma.es - - [10/Feb/1998:11:37:31 +0100] "GET / HTTP/1.0" 304 0
usu221.activanet.es - - [10/Feb/1998:11:55:49 +0100] "GET /tea/cap1/ce4f.html HTTP/1.0" 200 413
phoebe.lcc.uma.es - - [10/Feb/1998:12:13:25 +0100] "POST /cgi-bin/cgi-bueno/experto.cgi HTTP/1.0" 200 287
\end{verbatim}}

En este fichero, cada l\'{\i}nea representa el env\'{\i}o desde el servidor al cliente de una ``p\'agina'', lo que normalmente corresponde al env\'{\i}o directo de un fichero de hipertexto HTML, o bien un fichero de imagen GIF o JPG, o bien el resultado obtenido tras la ejecuci\'on de un programa en el servidor, etc. Cada l\'{\i}nea del fichero contiene estos datos por el siguiente orden: nombre o direcci\'on IP de la m\'aquina cliente, fecha exacta de la transmisi\'on, (lo que aparece entre corchetes), m\'etodo, nombre del fichero emitido y protocolo utilizado, (lo que aparece entre comillas dobles), y uno o dos n\'umeros de control.

\par Se desean construir mediante LEX los siguientes programas para analizar los accesos que se realizan a las paginas WWW de este servidor:

\begin{enumerate}[1)]
\item Se desea conocer cu\'antos accesos totales se han realizado, (usando la variable global \verb@int total@), cu\'antos de estos han sido a ficheros de imagen .gif o .jpg, (variable global \verb@int graficos@) y cu\'antos a ficheros de hipertexto .html, (variable global \verb@int hipertextos@).
\item Se desea conocer cu\'antos accesos totales ha habido, cu\'antos se han realizado desde el propio dominio del servidor (usando la variable global \verb@int locales@), y cu\'antos desde otros dominios. (usando \verb@int externos@). A estos efectos se considerará que todas las m\'aquinas cuyos nombres simb\'olicos que terminen por \verb@"lcc.uma.es"@ pertenecen al dominio, y que tambi\'en pertenecen al dominio todas aquellas cuya direcci\'on IP comience por la secuencia \verb@150.214.108@.
\item Se desea obtener una estad\'{\i}stica de frecuencia de accesos por intervalos horarios, dando valores a una variable global definida como una matriz de 24 elementos \verb@int horarios[24]@, de manera que, por ejemplo, \verb@horarios[17]@ representa todos los accesos realizados cualquier d\'{\i}a entre las 17:00 y las 17:59 horas.
\item Se desea obtener una estad\'{\i}stica de acceso a cada una de las p\'aginas. Para ello se debe definir una estructura de datos auxiliar que contenga esta informaci\'on y un m\'etodo de acceso a la misma que actualice los contadores conforme se lee el fichero de entrada. (No es necesario realizar la implementaci\'on de este/estos m\'etodo/s, basta con escribir su cabecera e indicar la funci\'on que realiza y situar correctamente las mismas dentro del programa LEX).
\item Finalmente, se propone realizar un programa que realice conjuntamente en una sola pasada las funciones de los cuatro anteriores.
\end{enumerate}

\par NOTAS:
\begin{itemize}
\item Para la realizaci\'on de este ejercicio no debe usarse ninguna variable auxiliar, distinta a las propias de LEX, salvo las que en su caso indica el propio enunciado.
\item El fichero de entrada es generado autom\'aticamente y por tanto no es necesario comprobar que antiene un formato correcto.
\end{itemize}

% Solución del ejercicio
\subsection*{SOLUCI\'ON}

\begin{verbatim}

%{
   #include "tabla.h"

   long total = 0;
   long graficos = 0;
   long hipertextos = 0;
   long locales = 0;
   long externos = 0;
   long horarios[24];
%}

%s PAGINA
%%

^[a-zA-Z0-9]+".lcc.uma.es"          |
^"150.214.108."[0-9]+               { locales++; }
^[a-zA-Z0-9.]+                      { externos++; }
[0-2][0-9]/:[0-9][0-9]:[0-9][0-9]\  { horarios[atoi(yytext)]++; }
\"[A-Z]+                            { BEGIN PAGINA; }
<PAGINA>[^\ \"]+.gif                |
<PAGINA>[^\ \"]+.jpg                { graficos++; apuntar(yytext); }
<PAGINA>[^\ \"]+.html               { hipertextos++; apuntar(yytext); }
<PAGINA>[^\ \"]+\"                  { BEGIN 0; }
\n                                  { total++; }
.                                   { ; /* ignorar el resto */ }

%%

int main() {

   int token;
   int i;

   for (i=0; i<24; i++)
      horarios[i] = 0;
   while ( token=yylex() != 0 );
   printf("Accesos totales:       %d\n",total);
   printf("Accesos a hipertextos: %d\n",hipertextos);
   printf("Accesos a graficos:    %d\n",graficos);
   printf("Accesos locales:       %d\n",locales);
   printf("Accesos externos:      %d\n",externos);
   printf("Accesos horarios:       [");
   for (i=0; i<24; i++)
      printf("%d ", horarios[i]);
   printf("]\n");
   printf("Accesos por paginas: \n");
   listartabla();
   return 0;
}
\end{verbatim}